...loading
2025-03-07
안녕하세요, 이번에는 블로그의 SEO 적용기를 작성해보려 합니다. 얼마전에 NextJS에서 SEO를 처리하는 방법에 대한 포스팅을 썼습니다.
해당 포스팅에서 Next의 metadata를 통해 SEO를 처리하는 방법에 대해 알아보았는데요, 이번에는 본 블로그의 코드에 직접 적용해보겠습니다. 사실 이전에 미리 구현한 Metadata 컴포넌트가 있었지만, 이번 포스팅에서 더 업그레이드 해보려합니다.
기존 코드에서도 metadata를 사용하여 SEO를 처리하고 있었습니다. 정적/동적 페이지에서 모두 사용할 수 있는 공용 컴포넌트를 만들어 적용했습니다. 그런데 얼마 전에 NextJs의 SEO처리에 대한 포스팅을 쓴 후 상당히 대충 구현한 컴포넌트였음이 반성됩니다.
import { Metadata } from "next"; import metadataString from "@/lib/metadata-string"; type MetadataProps = { page: string; isArticle?: boolean; articleSummary?: string; }; export function MetadataComponent({ page, isArticle, articleSummary, }: MetadataProps): Metadata { return { title: page === "Main" ? `Taki-Town` : `${page} | Taki-Town`, description: isArticle ? articleSummary : metadataString(page), robots: { index: true, follow: true, }, };
공용 컴포넌트의 내용입니다. props에 따라서 상응하는 결과를 내주는데, 너무 대충입니다. SEO를 처리하는 부분은 메인페이지와 포스팅페이지 뿐입니다. 가능하다면 모든 페이지에 따라 적절한 SEO처리를 해주는게 중요한데요, 따라서 더 구체적이고 세분화한 로직으로 바꿔보려 합니다. 그리고 자세히 보니, 해당 로직은 굳이 컴포넌트로 정의할 필요가 없습니다. 따라서 utils의 함수에서 처리해주도록 바꿉니다.
기존 코드에서는 하나의 로직에서 주요 페이지의 metadata를 한 번에 처리하려 하고 있습니다. 하지만 페이지 유형에 따라 조금씩 설정이 달라져야하는 metadata를 하나의 로직에서 다 처리해버린다면, 의존성이 높아집니다. 따라서 페이지 유형에 따라서 로직을 분리합니다. 분리 기준은 아래 세 가지와 같습니다.
: 페이지에서 동적으로 데이터를 받아와 metadata를 생성
: 홈페이지, 포스트 리스팅 페이지, 방명록 등에 적용합니다. 정적인 정보로 metadata를 생성합니다.
: 관리자 페이지로 SEO를 비활성화하는 설정을 포함한 metadata를 생성합니다.
위의 세 가지 유형의 페이지를 담당할 수 있는 metadata 생성기를 구현했습니다. 세 유형의 로직 모두 비슷하고, 약간의 데이터 설정만 다릅니다. 그렇기에 가장 중요한 포스팅/프로젝트 상세 페이지의 metadata 생성 코드만 확인해보겠습니다.
type ArticleCategory = "post" | "project"; type ArticleMetadataProps = { articleTitle: string; articleCategory: ArticleCategory; articleSummary: string; articleImageUrl: string; }; export function generateArticleMetadata({ articleTitle, articleCategory, articleSummary, articleImageUrl, }: ArticleMetadataProps): Metadata { return { title: `${articleTitle} | Taki-Town`, description: articleSummary, alternates: { canonical: `${process.env.PUBLIC_URL}/${articleCategory}/${articleTitle}`, }, openGraph: { title: articleTitle, description: articleSummary, url: `${process.env.PUBLIC_URL}/${articleCategory}/${articleTitle}`, images: [ { url: articleImageUrl, width: 1200, height: 630, alt: `아티클 '${articleTitle}'의 대표이미지`, }, ], }, robots: { index: true, follow: true, }, }; }
설정하는 metadata에 특별한 부분은 없습니다. 기본적인 내용과 openGraph를 통해 SNS에서의 링크 공유 시 최적화된 방식으로 전달되도록 설정합니다. 그리고 robots 속성을 통해 SEO와 크롤링에 대한 활성화도 열어줍니다. 다음에는 페이지 컴포넌트에서 구체적으로 어떻게 적용했는지 살펴보겠습니다.
// 포스팅 상세 페이지에서의 적용 // import etc.. import { generateArticleMetadata } from "@/utils/metadata"; export async function generateMetadata({ // 동적 메타데이터 생성 params, }: { params: { postSlug: string }; }) { const data = await fetchPostData(params.postSlug); return generateArticleMetadata({ // 동적으로 생성한 메타데이터 리턴 articleTitle: data.title, articleCategory: "post", articleSummary: data.summary, articleImageUrl: data.imageLink, }); } export default async function PostSlug({ params, }: { params: { postSlug: string }; }) { //... }
해당 포스팅 페이지는 동적으로 라우팅된 페이지입니다. 따라서 메타데이타 또한 동적으로 불러와야하기에, nextJs의 generateMetadata
를 사용하여 DB로부터 동적인 데이터 정보를 불러옵니다. 그리고 만들어둔 metadata 생성기를 적용하여, 해당 포스팅 내용에 최적화된 metadata를 반환받게 됩니다.
이상으로 metadata를 통한 SEO 적용기를 마치겠습니다. 추후 도메인을 사, 정식적인 사이트로 배포되었을 때 구글에서 잘 노출되면 좋겠습니다 ..ㅎ 그리고 코드를 리팩토링 하다보니, 부족한 부분들이 많이 보입니다. 조금 더 생각하면서 코드를 작성하는 습관을 들여야겠습니다. 다음에도 다른 작업일지로 돌아오겠습니다.
Comments